home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / CONTRIB / NOOF.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  9.7 KB  |  475 lines

  1.  
  2. /* XXX Very crufty code follows. */
  3.  
  4. #include <stdlib.h>
  5. #include <GL/glut.h>
  6.  
  7. #include <math.h>
  8. #ifndef _WIN32
  9. #include <unistd.h>
  10. #else
  11. #define random rand
  12. #define srandom srand
  13. #endif
  14. /* Some <math.h> files do not define M_PI... */
  15. #ifndef M_PI
  16. #define M_PI 3.14159265358979323846
  17. #endif
  18. #include <sys/types.h>
  19. #include <stdio.h>
  20.  
  21. /* For portability... */
  22. #undef fcos
  23. #undef fsin
  24. #define fcos  cos
  25. #define fsin  sin
  26.  
  27. /* --- shape parameters def'n --- */
  28. #define N_SHAPES 7
  29. float pos[N_SHAPES * 3];
  30. float dir[N_SHAPES * 3];
  31. float acc[N_SHAPES * 3];
  32. float col[N_SHAPES * 3];
  33. float hsv[N_SHAPES * 3];
  34. float hpr[N_SHAPES * 3];
  35. float ang[N_SHAPES];
  36. float spn[N_SHAPES];
  37. float sca[N_SHAPES];
  38. float geep[N_SHAPES];
  39. float peep[N_SHAPES];
  40. float speedsq[N_SHAPES];
  41. int blad[N_SHAPES];
  42.  
  43. float ht, wd;
  44.  
  45. void
  46. initshapes(int i)
  47. {
  48.   int k;
  49.   float f;
  50.  
  51.   /* random init of pos, dir, color */
  52.   for (k = i * 3; k <= i * 3 + 2; k++) {
  53.     f = random() / 2147483647.0;
  54.     pos[k] = f;
  55.     f = random() / 2147483647.0;
  56.     f = (f - 0.5) * 0.05;
  57.     dir[k] = f;
  58.     f = random() / 2147483647.0;
  59.     f = (f - 0.5) * 0.0002;
  60.     acc[k] = f;
  61.     f = random() / 2147483647.0;
  62.     col[k] = f;
  63.   }
  64.  
  65.   speedsq[i] = dir[i * 3] * dir[i * 3] + dir[i * 3 + 1] * dir[i * 3 + 1];
  66.   f = random() / 2147483647.0;
  67.   blad[i] = 2 + (int) (f * 17.0);
  68.   f = random() / 2147483647.0;
  69.   ang[i] = f;
  70.   f = random() / 2147483647.0;
  71.   spn[i] = (f - 0.5) * 40.0 / (10 + blad[i]);
  72.   f = random() / 2147483647.0;
  73.   sca[i] = (f * 0.1 + 0.08);
  74.   dir[i * 3] *= sca[i];
  75.   dir[i * 3 + 1] *= sca[i];
  76.  
  77.   f = random() / 2147483647.0;
  78.   hsv[i * 3] = f * 360.0;
  79.  
  80.   f = random() / 2147483647.0;
  81.   hsv[i * 3 + 1] = f * 0.6 + 0.4;
  82.  
  83.   f = random() / 2147483647.0;
  84.   hsv[i * 3 + 2] = f * 0.7 + 0.3;
  85.  
  86.   f = random() / 2147483647.0;
  87.   hpr[i * 3] = f * 0.005 * 360.0;
  88.   f = random() / 2147483647.0;
  89.   hpr[i * 3 + 1] = f * 0.03;
  90.   f = random() / 2147483647.0;
  91.   hpr[i * 3 + 2] = f * 0.02;
  92.  
  93.   geep[i] = 0;
  94.   f = random() / 2147483647.0;
  95.   peep[i] = 0.01 + f * 0.2;
  96. }
  97.  
  98. int tko = 0;
  99.  
  100. float bladeratio[] =
  101. {
  102.   /* nblades = 2..7 */
  103.   0.0, 0.0, 3.00000, 1.73205, 1.00000, 0.72654, 0.57735, 0.48157,
  104.   /* 8..13 */
  105.   0.41421, 0.36397, 0.19076, 0.29363, 0.26795, 0.24648,
  106.   /* 14..19 */
  107.   0.22824, 0.21256, 0.19891, 0.18693, 0.17633, 0.16687,
  108. };
  109.  
  110. void
  111. drawleaf(int l)
  112. {
  113.  
  114.   int b, blades;
  115.   float x, y;
  116.   float wobble;
  117.  
  118.   blades = blad[l];
  119.  
  120.   y = 0.10 * fsin(geep[l] * M_PI / 180.0) + 0.099 * fsin(geep[l] * 5.12 * M_PI / 180.0);
  121.   if (y < 0)
  122.     y = -y;
  123.   x = 0.15 * fcos(geep[l] * M_PI / 180.0) + 0.149 * fcos(geep[l] * 5.12 * M_PI / 180.0);
  124.   if (x < 0.0)
  125.     x = 0.0 - x;
  126.   if (y < 0.001 && x > 0.000002 && ((tko & 0x1) == 0)) {
  127.     initshapes(l);      /* let it become reborn as something
  128.                            else */
  129.     tko++;
  130.     return;
  131.   } {
  132.     float w1 = fsin(geep[l] * 15.3 * M_PI / 180.0);
  133.     wobble = 3.0 + 2.00 * fsin(geep[l] * 0.4 * M_PI / 180.0) + 3.94261 * w1;
  134.   }
  135.  
  136.   /**
  137.   if(blades == 2) if (y > 3.000*x) y = x*3.000;
  138.   if(blades == 3) if (y > 1.732*x) y = x*1.732;
  139.   if(blades == 4) if (y >       x) y = x;
  140.   if(blades == 5) if (y > 0.726*x) y = x*0.726;
  141.   if(blades == 6) if (y > 0.577*x) y = x*0.577;
  142.   if(blades == 7) if (y > 0.481*x) y = x*0.481;
  143.   if(blades == 8) if (y > 0.414*x) y = x*0.414;
  144.   */
  145.   if (y > x * bladeratio[blades])
  146.     y = x * bladeratio[blades];
  147.  
  148.   for (b = 0; b < blades; b++) {
  149.     glPushMatrix();
  150.     glTranslatef(pos[l * 3], pos[l * 3 + 1], pos[l * 3 + 2]);
  151.     glRotatef(ang[l] + b * (360.0 / blades), 0.0, 0.0, 1.0);
  152.     glScalef(wobble * sca[l], wobble * sca[l], wobble * sca[l]);
  153.     /**
  154.     if(tko & 0x40000) glColor3f(col[l*3], col[l*3+1], col[l*3+2]); 
  155.     else
  156.     */
  157.     glColor4ub(0, 0, 0, 0x60);
  158.  
  159.     /* constrain geep cooridinates here XXX */
  160.     glEnable(GL_BLEND);
  161.  
  162.     glBegin(GL_TRIANGLE_STRIP);
  163.     glVertex2f(x * sca[l], 0.0);
  164.     glVertex2f(x, y);
  165.     glVertex2f(x, -y);  /* C */
  166.     glVertex2f(0.3, 0.0);  /* D */
  167.     glEnd();
  168.  
  169.     /**
  170.     if(tko++ & 0x40000) glColor3f(0,0,0);
  171.     else
  172.     */
  173.     glColor3f(col[l * 3], col[l * 3 + 1], col[l * 3 + 2]);
  174.     glBegin(GL_LINE_LOOP);
  175.     glVertex2f(x * sca[l], 0.0);
  176.     glVertex2f(x, y);
  177.     glVertex2f(0.3, 0.0);  /* D */
  178.     glVertex2f(x, -y);  /* C */
  179.     glEnd();
  180.     glDisable(GL_BLEND);
  181.  
  182.     glPopMatrix();
  183.   }
  184. }
  185.  
  186. void
  187. motionUpdate(int t)
  188. {
  189.   if (pos[t * 3] < -sca[t] * wd && dir[t * 3] < 0.0) {
  190.     dir[t * 3] = -dir[t * 3];
  191.   /**
  192.   acc[t*3+1] += 0.8*acc[t*3];
  193.   acc[t*3] = -0.8*acc[t*3];
  194.   */
  195.   } else if (pos[t * 3] > (1 + sca[t]) * wd && dir[t * 3] > 0.0) {
  196.     dir[t * 3] = -dir[t * 3];
  197.     /**
  198.     acc[t*3+1] += 0.8*acc[t*3];
  199.     acc[t*3] = -0.8*acc[t*3];
  200.     */
  201.   } else if (pos[t * 3 + 1] < -sca[t] * ht && dir[t * 3 + 1] < 0.0) {
  202.     dir[t * 3 + 1] = -dir[t * 3 + 1];
  203.     /**
  204.     acc[t*3] += 0.8*acc[t*3+1];
  205.     acc[t*3+1] = -0.8*acc[t*3+1];
  206.     */
  207.   } else if (pos[t * 3 + 1] > (1 + sca[t]) * ht && dir[t * 3 + 1] > 0.0) {
  208.     dir[t * 3 + 1] = -dir[t * 3 + 1];
  209.     /**
  210.     acc[t*3] += 0.8*acc[t*3+1];
  211.     acc[t*3+1] = -0.8*acc[t*3+1];
  212.     */
  213.   }
  214.  
  215.   pos[t * 3] += dir[t * 3];
  216.   pos[t * 3 + 1] += dir[t * 3 + 1];
  217.   /**
  218.   dir[t*3]   += acc[t*3];
  219.   dir[t*3+1] += acc[t*3+1];
  220.   */
  221.   ang[t] += spn[t];
  222.   geep[t] += peep[t];
  223.   if (geep[t] > 360 * 5.0)
  224.     geep[t] -= 360 * 5.0;
  225.   if (ang[t] < 0.0) {
  226.     ang[t] += 360.0;
  227.   }
  228.   if (ang[t] > 360.0) {
  229.     ang[t] -= 360.0;
  230.   }
  231. }
  232.  
  233. void
  234. colorUpdate(int i)
  235. {
  236.   if (hsv[i * 3 + 1] <= 0.5 && hpr[i * 3 + 1] < 0.0)
  237.     hpr[i * 3 + 1] = -hpr[i * 3 + 1];  /* adjust s */
  238.   if (hsv[i * 3 + 1] >= 1.0 && hpr[i * 3 + 1] > 0.0)
  239.     hpr[i * 3 + 1] = -hpr[i * 3 + 1];  /* adjust s */
  240.   if (hsv[i * 3 + 2] <= 0.4 && hpr[i * 3 + 2] < 0.0)
  241.     hpr[i * 3 + 2] = -hpr[i * 3 + 2];  /* adjust s */
  242.   if (hsv[i * 3 + 2] >= 1.0 && hpr[i * 3 + 2] > 0.0)
  243.     hpr[i * 3 + 2] = -hpr[i * 3 + 2];  /* adjust s */
  244.  
  245.   hsv[i * 3] += hpr[i * 3];
  246.   hsv[i * 3 + 1] += hpr[i * 3 + 1];
  247.   hsv[i * 3 + 2] += hpr[i * 3 + 2];
  248.  
  249.   /* --- hsv -> rgb --- */
  250. #define H(hhh) hhh[i*3  ]
  251. #define S(hhh) hhh[i*3+1]
  252. #define V(hhh) hhh[i*3+2]
  253.  
  254. #define R(hhh) hhh[i*3  ]
  255. #define G(hhh) hhh[i*3+1]
  256. #define B(hhh) hhh[i*3+2]
  257.  
  258.   if (V(hsv) < 0.0)
  259.     V(hsv) = 0.0;
  260.   if (V(hsv) > 1.0)
  261.     V(hsv) = 1.0;
  262.   if (S(hsv) <= 0.0) {
  263.     R(col) = V(hsv);
  264.     G(col) = V(hsv);
  265.     B(col) = V(hsv);
  266.   } else {
  267.     float f, h, p, q, t, v;
  268.     int hi;
  269.  
  270.     while (H(hsv) < 0.0)
  271.       H(hsv) += 360.0;
  272.     while (H(hsv) >= 360.0)
  273.       H(hsv) -= 360.0;
  274.  
  275.     if (S(hsv) < 0.0)
  276.       S(hsv) = 0.0;
  277.     if (S(hsv) > 1.0)
  278.       S(hsv) = 1.0;
  279.  
  280.     h = H(hsv) / 60.0;
  281.     hi = (int) (h);
  282.     f = h - hi;
  283.     v = V(hsv);
  284.     p = V(hsv) * (1 - S(hsv));
  285.     q = V(hsv) * (1 - S(hsv) * f);
  286.     t = V(hsv) * (1 - S(hsv) * (1 - f));
  287.  
  288.     if (hi <= 0) {
  289.       R(col) = v;
  290.       G(col) = t;
  291.       B(col) = p;
  292.     } else if (hi == 1) {
  293.       R(col) = q;
  294.       G(col) = v;
  295.       B(col) = p;
  296.     } else if (hi == 2) {
  297.       R(col) = p;
  298.       G(col) = v;
  299.       B(col) = t;
  300.     } else if (hi == 3) {
  301.       R(col) = p;
  302.       G(col) = q;
  303.       B(col) = v;
  304.     } else if (hi == 4) {
  305.       R(col) = t;
  306.       G(col) = p;
  307.       B(col) = v;
  308.     } else {
  309.       R(col) = v;
  310.       G(col) = p;
  311.       B(col) = q;
  312.     }
  313.   }
  314. }
  315.  
  316. void
  317. gravity(float fx)
  318. {
  319.   int a, b;
  320.  
  321.   for (a = 0; a < N_SHAPES; a++) {
  322.     for (b = 0; b < a; b++) {
  323.       float t, d2;
  324.  
  325.       t = pos[b * 3] - pos[a * 3];
  326.       d2 = t * t;
  327.       t = pos[b * 3 + 1] - pos[a * 3 + 1];
  328.       d2 += t * t;
  329.       if (d2 < 0.000001)
  330.         d2 = 0.00001;
  331.       if (d2 < 0.1) {
  332.  
  333.         float v0, v1, z;
  334.         v0 = pos[b * 3] - pos[a * 3];
  335.         v1 = pos[b * 3 + 1] - pos[a * 3 + 1];
  336.  
  337.         z = 0.00000001 * fx / (d2);
  338.  
  339.         dir[a * 3] += v0 * z * sca[b];
  340.         dir[b * 3] += -v0 * z * sca[a];
  341.         dir[a * 3 + 1] += v1 * z * sca[b];
  342.         dir[b * 3 + 1] += -v1 * z * sca[a];
  343.  
  344.       }
  345.     }
  346.     /** apply brakes
  347.     if(dir[a*3]*dir[a*3] + dir[a*3+1]*dir[a*3+1]
  348.       > 0.0001) {
  349.       dir[a*3] *= 0.9;
  350.       dir[a*3+1] *= 0.9;
  351.     }
  352.     */
  353.   }
  354. }
  355. void
  356. oneFrame(void)
  357. {
  358.   int i;
  359.  
  360.   /**
  361.   if((random() & 0xff) == 0x34){
  362.     glClear(GL_COLOR_BUFFER_BIT);
  363.   }
  364.  
  365.   if((tko & 0x1f) == 0x1f){
  366.     glEnable(GL_BLEND);
  367.     glColor4f(0.0, 0.0, 0.0, 0.09);
  368.     glRectf(0.0, 0.0, wd, ht);
  369.     glDisable(GL_BLEND);
  370. #ifdef __sgi
  371.     sginap(0);
  372. #endif
  373.   }
  374.   */
  375.   gravity(-2.0);
  376.   for (i = 0; i < N_SHAPES; i++) {
  377.     motionUpdate(i);
  378. #ifdef __sgi
  379.     sginap(0);
  380. #endif
  381.     colorUpdate(i);
  382. #ifdef __sgi
  383.     sginap(0);
  384. #endif
  385.     drawleaf(i);
  386. #ifdef __sgi
  387.     sginap(0);
  388. #endif
  389.  
  390.   }
  391.   glFlush();
  392. }
  393.  
  394. void
  395. display(void)
  396. {
  397.   glClear(GL_COLOR_BUFFER_BIT);
  398. }
  399.  
  400. void
  401. myReshape(int w, int h)
  402. {
  403.   glViewport(0, 0, w, h);
  404.   glMatrixMode(GL_PROJECTION);
  405.   glLoadIdentity();
  406.   if (w <= h) {
  407.     wd = 1.0;
  408.     ht = (GLfloat) h / (GLfloat) w;
  409.     glOrtho(0.0, 1.0,
  410.       0.0, 1.0 * (GLfloat) h / (GLfloat) w,
  411.       -16.0, 4.0);
  412.   } else {
  413.     wd = (GLfloat) w / (GLfloat) h;
  414.     ht = 1.0;
  415.     glOrtho(0.0, 1.0 * (GLfloat) w / (GLfloat) h,
  416.       0.0, 1.0,
  417.       -16.0, 4.0);
  418.   }
  419.   glMatrixMode(GL_MODELVIEW);
  420.   glLoadIdentity();
  421. }
  422.  
  423. void
  424. visibility(int status)
  425. {
  426.   if (status == GLUT_VISIBLE) {
  427.     glutIdleFunc(oneFrame);
  428.   } else {
  429.     glutIdleFunc(NULL);
  430.   }
  431.  
  432. }
  433.  
  434. void
  435. myinit(void)
  436. {
  437.   int i;
  438.   srandom(getpid());
  439.   glClearColor(0.0, 0.0, 0.0, 1.0);
  440.   glEnable(GL_LINE_SMOOTH);
  441.   glShadeModel(GL_FLAT);
  442.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  443.   for (i = 0; i < N_SHAPES; i++)
  444.     initshapes(i);
  445.   myReshape(200, 200);
  446. }
  447.  
  448. /* ARGSUSED1 */
  449. void
  450. keys(unsigned char c, int x, int y)
  451. {
  452.  
  453.   if (c == 0x1b)
  454.     exit(0);            /* escape */
  455. }
  456.  
  457. int
  458. main(int argc, char **argv)
  459. {
  460.   glutInit(&argc, argv);
  461.   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
  462.   glutInitWindowSize(300, 300);
  463.   glutCreateWindow(argv[0]);
  464.  
  465.   myinit();
  466.   glutReshapeFunc(myReshape);
  467.   glutDisplayFunc(display);
  468.   glutKeyboardFunc(keys);
  469.   glutVisibilityFunc(visibility);
  470.   glutIdleFunc(oneFrame);
  471.   glutPostRedisplay();
  472.   glutMainLoop();
  473.   return 0;             /* ANSI C requires main to return int. */
  474. }
  475.